home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_400
/
425_01
/
tar
/
streamer.c
< prev
next >
Wrap
Text File
|
1980-07-23
|
20KB
|
710 lines
#ifdef __TURBOC__
#include <dos.h>
#include <errno.h>
#include <string.h>
#include "qic02.h"
/*****************************************************\
* Quarter-Inch-Cartridge no. 02 standart error list *
\*****************************************************/
static char *err[] = {
"udefined error",
"Ok",
"reset in progress", /* hardware status */
"end of recorded media",
"bus parity error",
"beginning of media",
"marginal block detected",
"no data detected",
"illegal command",
"timeout expired", /* software flag */
"file mark detected",
"block not located",
"unrecoverable data error",
"end of medium",
"write protected",
"device fault",
"cartridge not in place",
"drive busy", /* software error codes */
"device not opened",
"device already opened",
};
char **qic02_errlist = err+1;
int qic02_nerr = sizeof(err)/sizeof(*err) - 1;
/****************************************************\
* Quarter-Inch-Cartridge no. 02 standart interface *
\****************************************************/
extern unsigned long timer(void);
extern unsigned long suspend_value(unsigned);
extern void suspend(unsigned long);
extern void interrupt cthandle();
extern long ptr2abs(void far *);
static unsigned long wait03us, wait25ms;
#define CT_OPENED 0x08
#define CT_CHECKED 0x10
#define CT_EVENT 0x20
#define CT_PROTECT 0x40
#define MASK_BOARD 0x7f
#define SKIP_RESET 0x80
/* Calculate number of ticks by 300 ms units */
#define TIMEOUT(x) (int)((3*119318L*(x) + 65535L) / 65536L)
#define MINTIME TIMEOUT(1)
#define MAXTIME TIMEOUT(1000)
#define WAITIME TIMEOUT(10)
#define HALT_CPU /*__emit__(0xf4)*/
#define dim(x) (sizeof(x)/sizeof(*(x)))
#define NTRY 3
#define Q2_READBIT 0x80
#define DMA_WRDEV 8
#define DMA_RDDEV 4
#define ALIASLEN 8
struct _ct_define {
char (*aliases)[ALIASLEN]; int naliases;
WORD valid_base, off_control, off_data, off_launch, off_clear;
BYTE mask_reset, val_reset;
BYTE mask_event, not_event;
BYTE mask_ready, not_ready;
BYTE mask_excep, not_excep;
BYTE mask_dma, done_dma;
BYTE mask_xfer, no_xfer;
BYTE set_reset, set_request, set_online;
BYTE ienable, denable, dma_valid, rundma[8];
};
static char archivenames[][ALIASLEN]={
"archive","fastape", "sc499", "sc-499", "sc402", "sc-402",
};
static char everexnames [][ALIASLEN]={
"everex", "sc409a", "sc-409a",
};
static char wangteknames[][ALIASLEN]={
"wangtek",
};
struct _ct_define sc499 = {
archivenames, dim(archivenames),
0x3f8, 1, 0, 2, 3,
0xf0, 0x50,
0x80, 0x80,
0x40, 0x40,
0x20, 0x20,
0x10, 0x10,
0x08, 0x00,
0x80, 0x40, 0,
0x20, 0x10, 0x0A, { 0, 0, 0, 0, 0, 0, 0, 0 },
};
struct _ct_define sc409a = {
everexnames, dim(everexnames),
0x3ff, 0, 1, UNUSED, UNUSED,
7, 5,
0, 0,
1, 1,
2, 2,
0, 0,
4, 4,
2, 4, 1,
0x40, 0, 0x0E, { 0, 8, 8, 8, 0, 0, 0, 0 },
};
struct _ct_define wangtek = {
wangteknames, dim(wangteknames),
0x3ff, 0, 1, UNUSED, UNUSED,
7, 5,
0, 0,
1, 1,
2, 2,
0, 0,
4, 4,
2, 4, 1,
0, 0, 0x0E, { 0, 8, 8, 16, 0, 0, 0, 0 },
};
struct _ct_define *ct_list[] = {
&sc499, &sc409a, &wangtek
};
struct _ct_pic {
WORD base;
BYTE ack, chain;
void interrupt (*old)();
int number; BYTE save;
} ct_pic;
struct _ct_dma {
WORD page, address, counter;
WORD mask, mode, clear;
BYTE read, write;
} ct_dma;
BYTE lastcmd = UNUSED;
WORD ct_error;
volatile struct _ct_psw {
BYTE flags;
BYTE input;
} ct_psw;
struct _ct_control {
WORD control, data, launch, clear;
BYTE mask_reset, val_reset;
BYTE mask_event, not_event;
BYTE mask_ready, not_ready;
BYTE mask_excep, not_excep;
BYTE mask_state, inv_state;
BYTE mask_xfer, no_xfer;
BYTE mask_dma, done_dma;
BYTE do_reset, request, online;
BYTE int_enable, done_enable, dma_enable;
} ct_set;
static WORD ct_error;
static BYTE statbuf[6];
#define ctlport (ct_set.control)
#define cmdport (ct_set.data)
#define statport (ct_set.control)
#define dataport (ct_set.data)
#define DMAGO (ct_set.launch)
#define DMACL (ct_set.clear)
#define MASK_RESET ct_set.mask_reset
#define VAL_RESET ct_set.val_reset
#define MASK_READY ct_set.mask_ready
#define NOT_READY ct_set.not_ready
#define MASK_EXCEP ct_set.mask_excep
#define NOT_EXCEP ct_set.not_excep
#define MASK_STATE ct_set.mask_state
#define INV_STATE ct_set.inv_state
#define DIRC ct_set.mask_xfer
#define XOFF ct_set.no_xfer
#define ON ct_set.online
#define REQ ct_set.request
#define RESET ct_set.do_reset
#define EI ct_set.int_enable
#define ED ct_set.done_enable
#define DMA ct_set.dma_enable
#define INP ct_psw.input
#define DMA_MAIN ct_dma.mask
#define WAIT_READY(t)\
for ((t)=timer(); ((INP=inportb(statport))&MASK_READY)==NOT_READY;)\
{ if (timer()-(t) > MINTIME) goto error; }
#define WAIT_BUSY(t)\
for ((t)=timer(); ((INP=inportb(statport))&MASK_READY)!=NOT_READY;)\
{ if (timer()-(t) > MINTIME) goto error; }
static int ct_iobyte(int c, unsigned char *p, unsigned length, unsigned tout)
{
register i;
register long t, t0;
#if 0
/* read-only now */ if (!(c & Q2_READBIT)) goto error;
#endif
ct_psw.flags &= ~CT_CHECKED;
outportb(cmdport, lastcmd=c);
outportb(ctlport, REQ);
WAIT_READY(t);
outportb(ctlport, ON); /* Clear request */
WAIT_BUSY(t);
t0 = timer();
i = c & Q2_READBIT ? XOFF : XOFF^DIRC;
while (((INP=inportb(statport)) & DIRC)==XOFF) {
if (timer()-t0 > tout) goto error;
}
for (i=0; i<length; i++) {
WAIT_READY(t);
if (c & Q2_READBIT) {
p[i] = inportb(dataport);
} else {
outportb(dataport, p[i]);
}
outportb(ctlport, REQ);
suspend(wait03us);
WAIT_BUSY(t);
outportb(ctlport, ON);
}
return i;
error:
ct_error = Q2E_DEAD;
ct_psw.flags |= CT_CHECKED;
errno = EFAULT;
return -1;
}
static int ct_test(void)
{
register n;
register long t;
for (t=timer(); ((INP=inportb(statport))&MASK_STATE)==INV_STATE;) {
if (timer()-t > MINTIME) {
ct_error = Q2E_BUSY; goto end;
}
HALT_CPU;
}
for (n=NTRY; n; n--) {
if (ct_iobyte(Q2_RDSTAT, statbuf, 6, TIMEOUT(10)) == 6) {
ct_error = (statbuf[0] & Q2_ERRFLAG) ?
(statbuf[0] & Q2_ERRMASK) << 8 : 0;
if (statbuf[1] & Q2_ERRFLAG) ct_error |= statbuf[1] & Q2_ERRMASK;
break;
}
}
end:
ct_psw.flags |= CT_CHECKED;
return ct_error;
}
static int ct_wait(BYTE mask, BYTE val, unsigned long t0, unsigned tout)
{
while (((INP=inportb(statport)) & mask) == val) {
if ((INP & MASK_EXCEP) != NOT_EXCEP) return ct_test();
if (timer()-t0 > tout) {
ct_psw.flags |= CT_CHECKED;
return ct_error = (INP&MASK_READY)==NOT_READY ? Q2E_BUSY : Q2E_DEAD;
}
HALT_CPU;
}
return 0;
}
static int ct_reset(void)
{
register long t;
outportb(ctlport, ct_set.do_reset);
suspend(wait25ms);
outportb(DMACL != UNUSED ? DMACL : ctlport, ON);
t = timer();
while ((((INP=inportb(statport)) & MASK_RESET) != VAL_RESET)) {
if (timer()-t > MINTIME) goto error; HALT_CPU;
}
while (!(ct_test() & Q2E_POR)) {
if (timer()-t > MAXTIME) goto error; HALT_CPU;
}
while (ct_test() & Q2E_POR) {
if (timer()-t > MAXTIME) goto error; HALT_CPU;
}
while ((INP=inportb(statport) & MASK_STATE) == INV_STATE) {
if (timer()-t > MAXTIME) goto error; HALT_CPU;
}
return 0;
error:
return -1;
}
int ct_errbit(register unsigned m)
{
register n = 0;
if (m) {
if (m & Q2E_DEAD) m &= Q2E_DEAD;
else if (m & Q2E_HARD) m &= Q2E_HARD;
for (n=16; n && !(m & 0x8000); --n, m<<=1);
}